/**
 * MOAB, a Mesh-Oriented datABase, is a software component for creating,
 * storing and accessing finite element mesh data.
 *
 * Copyright 2004 Sandia Corporation.  Under the terms of Contract
 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
 * retains certain rights in this software.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 */

//-------------------------------------------------------------------------
// Filename      : ReadNASTRAN.hpp
//
// Purpose       : NASTRAN file reader
//
// Creator       : Brandon Smith
//
// Date          : 08/2009
//
//-------------------------------------------------------------------------

#ifndef READNASTRAN_HPP
#define READNASTRAN_HPP

#ifndef IS_BUILDING_MB
#error "ReadNASTRAN.hpp isn't supposed to be included into an application"
#endif

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>

#include "moab/Interface.hpp"
#include "moab/ReaderIface.hpp"
#include "FileTokenizer.hpp"
#include "moab/RangeMap.hpp"

namespace moab
{

class ReadUtilIface;

class ReadNASTRAN : public ReaderIface
{

  public:
    // factory method
    static ReaderIface* factory( Interface* );

    ErrorCode load_file( const char* file_name, const EntityHandle* file_set, const FileOptions& opts,
                         const SubsetList* subset_list = 0, const Tag* file_id_tag = 0 );
    // constructor
    ReadNASTRAN( Interface* impl = NULL );

    // destructor
    virtual ~ReadNASTRAN();

    ErrorCode read_tag_values( const char* file_name, const char* tag_name, const FileOptions& opts,
                               std::vector< int >& tag_values_out, const SubsetList* subset_list = 0 );

  protected:
  private:
    // read mesh interface
    ReadUtilIface* readMeshIface;

    // MOAB Interface
    Interface* MBI;

    RangeMap< int, EntityHandle > nodeIdMap, elemIdMap;

    enum line_format
    {
        SMALL_FIELD,
        LARGE_FIELD,
        FREE_FIELD
    };

    ErrorCode determine_line_format( const std::string& line, line_format& format );

    ErrorCode tokenize_line( const std::string& line, const line_format format, std::vector< std::string >& tokens );

    ErrorCode determine_entity_type( const std::string& token, EntityType& type );

    ErrorCode get_real( const std::string&, double& real );

    ErrorCode read_node( const std::vector< std::string >& tokens, const bool debug, double* coord_arrays[3],
                         int& node_id );

    ErrorCode read_element( const std::vector< std::string >& tokens, std::vector< Range >& materials,
                            const EntityType element_type, const bool debug );

    ErrorCode create_materials( const std::vector< Range >& materials );

    ErrorCode assign_ids( const Tag* file_id_tag );
};

}  // namespace moab

#endif
